
import { DateUtils } from '../utils/date.js';
import { Utils } from '../utils/utils.js';
import { BaseControl } from './BaseControl.js';
import { Validators } from './Validators.js';
import { DEFAULT_FORM_ITEM } from './form.const.js';
// import { FormControlData, ValidatorFn, ValidatorTypes, Option, Modifier, PlaceholderChangeFn, FormControlLog, OptionsChangeFn, PressEnterFn, SelectorType, SelectorChangeFn, ControlErrorType, UploadType, LabelStyleChangeFn, LabelChangeFn, ShowValueChangeFn, SelectorStyleChangeFn, ColorChangeFn, ValueChangeFn, CSSProperties } from './form.interface';


/**
 * 获取 Option 的 label
 * @param {string} key 
 * @param {Option[]} options 
 * @returns {Option | undefined}
 */
const getOptionLable = (key, options) => {
	let result = options.find(v => v.value === key);
	if (result) {
		return result;
	}
	options.forEach(option => {
		const children = option.children ?? [];
		const res = getOptionLable(key, children);
		if (res !== undefined) {
			result = res;
		}
	});
	return result;
}
// @ReadonlyFormControlDecorator
// @hiddenDecorator()
export class FormControl extends BaseControl {

	/**
	 * @description 构造函数创建对象
	 * @param {FormControlData}
	 */
	constructor(
		data = {}
	) {
		super();
		this.controlData = { ...Utils.clone(DEFAULT_FORM_ITEM), ...data };
		/** 日志开关 */
		if (this.controlData.loggingSwitch === true) {
			this.loggingSwitch = true;
		}
		/** 验证器设定 */
		if (Utils.isArray(this.controlData.validators)) {
			this.setValidators(this.controlData.validators ?? []);
		}
		/** 必填设定 */
		if (this.controlData.required === true) {
			this.required = true;
		}
		/** 只读设定 */
		if (this.controlData.readonly === true) {
			this.readonly = true;
		}
		/** 隐藏设定 */
		if (this.controlData.hidden === true) {
			this.hidden = true;
			// console.log(this.controlData.label, this);
		}
		/** 样式 */
		if (this.controlData.style) {
			this.style = this.controlData.style;
		}
		/** 标签样式 */
		if (this.controlData.labelStyle) {
			this.labelStyle = this.controlData.labelStyle;
		}
		/** 选择器样式 */
		if (this.controlData.selectorStyle) {
			this.selectorStyle = this.controlData.selectorStyle;
		}
		/** 禁用设定 */
		if (this.controlData.disabled === true) {
			this.disabled = true;
		}
		/** 下拉数据 */
		if (Array.isArray(this.controlData.options) && this.controlData.options.length > 0) {
			this._options = this.controlData.options;
		}
		/** placeholder 设定 */
		if (this.controlData.placeholder) {
			this.placeholder = this.controlData.placeholder;
		}
		/** 选择器 设定 */
		if (this.controlData.selector) {
			this.selector = this.controlData.selector;
		}
		/** 标签 设定 */
		if (this.controlData.label) {
			this.label = this.controlData.label;
		}
		/** 值设定 */
		if (this.controlData.value !== undefined) {
			this.setValue(this.controlData.value);
		}
		/** 显示值 */
		if (this.controlData.showValue !== undefined) {
			this.showValue = this.controlData.showValue;
		}
		/** Enter */
		if (Utils.isFunction(this.controlData.onPressEnter)) {
			this.onPressEnter = this.controlData.onPressEnter;
		}
		if (this.selector === 'files') {
			if (Utils.isEmpty(this.value) || !Utils.isArray(this.value)) {
				this.setValue([]);
			}
		}
		/** 多选 */
		this.multiple = this.controlData.multiple ?? false;
		/** 上传文件类型 */
		if (this.controlData.uploadType) {
			this.uploadType = this.controlData.uploadType;
		}
		/** 开始结束值数据类型 */
		if (this.controlData.startEndType) {
			this.startEndType = this.controlData.startEndType;
		}
		/** 清除按钮 */
		if (this.controlData.allowClear) {
			this.allowClear = true;
		}
		/** 是否显示标签 */
		this.showLabel = this.controlData.showLabel;
	}
	/** 文件多选 */
	multiple = false;
	/** 上传文件类型 */
	uploadType = 'file';
	/** 清除按钮 */
	allowClear = false;


	/**
	 * @description FormControl 的值 只读 any
	 */
	_value = undefined;
	get value() {
		return this._value;
	}
	set value(v) {
		this.setValue(v);
	}
	/**
	 * @description 设置值
	 */
	setValue = (v, modifier = 'bot') => {
		if (this._value === v) {
			return;
		}
		if (this._setInitValue) {
			this._setInitValue(v);
		}
		this._value = v;
		// 脏检查
		this._updateDirty();
		// 验证检测
		this._updateValid();
		// 记录日志
		if (this.loggingSwitch && modifier !== 'user') {
			if (this.logs.length === 0) {
				this.logs.push({ value: v, modifier: 'init', createTime: DateUtils.dateFormat(+new Date(), 'yyyy-MM-dd hh:mm:ss.sss'), diff: 0 });
			} else {
				const now = +new Date();
				const last = +new Date(this.logs[this.logs.length - 1].createTime);
				const diff = now - last;
				this.logs.push({ value: v, modifier, createTime: DateUtils.dateFormat(now, 'yyyy-MM-dd hh:mm:ss.sss'), diff });
			}

		}
		// 数据改变回调
		this.runValueChangeCallbacks(this._value);
		if (this.parent) {
			this.parent.onCollectionChange();
		}
		return this;
	};

	/**
	 *  初始值
	 */
	 _initValue = null;
	/** 初始值设定 */
	_setInitValue = (v) => {
		// 初始值设定
		this._initValue = v;
		// 初始值设定，只能一次
		this._setInitValue = null;
	};
	reset = () => {
		this.setValue(this._initValue);
		return this;
	};

	/**
	 * @description 验证结果 只读 boolean
	 */
	_valid = true;
	get valid() {
		return this._valid;
	}
	/**
	 * @description 验证器 Array<string>
	 */
	_validators = [];
	/**
	 * @description 验证
	 */
	_updateValid = async () => {
		const errors = [];
		// 上次验证结果
		const provValid = this._valid;
		// 本次验证结果
		this._valid = true;
		// 当 this.disabled === true，取消验证
		if (this.disabled === true) {
			this._valid = true;
			this._errors = [];
			return;
		}

		for (let i = 0; i < this._validators.length; i++) {
			const validator = this._validators[i];
			let validRes = { valid: true, type: '', data: null };
			if (Utils.isString(validator) && Utils.isValidKey(validator, Validators)) {
				const callback = Validators[validator];
				// 唯一性验证
				if (validator === 'unique') {
				} else if (this.hidden) { // 隐藏字段不参与验证

				} else {
					validRes = callback(this.value);
				}
				if (validRes.valid === false) {
					this._valid = false;
					errors.push({ type: validRes.type, data: validRes.data });
				}
			}
			if (Utils.isFunction(validator)) {
				const callback = validator;
				const validRes = callback(this.value);
				if (validRes.valid === false) {
					this._valid = false;
					errors.push({ type: validRes.type, data: validRes.data });
				}
			}

		}

		this._errors = errors;
		// 当 this.#valid 发生改变时，回调validChangeCallbacks
		if (provValid !== this._valid) {
			this.runValidChangeCallbacks(this._valid);
		}
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	}
	/**
	 * @description 设置验证器
	 */
	setValidators = (validators) => {
		this._validators = validators;
		this._updateValid();
		return this;
	}
	/** 添加验证器 */
	addValidators = (type) => {
		const index = this._validators.findIndex(v => v === type);
		if (index === -1) {
			this._validators.push(type);
		}
		this._updateValid();
		return this;
	}
	/** 添加验证器 */
	addFnValidator = (validatorFn) => {
		const index = this._validators.findIndex(v => v === validatorFn);
		if (index === -1) {
			this._validators.push(validatorFn);
		}
		this._updateValid();
		return this;
	}
	/** 移除验证器 */
	removeValidators = (type) => {
		const index = this._validators.findIndex(v => v === type);
		if (index !== -1) {
			this._validators.splice(index, 1);
		}
		this._updateValid();
		return this;
	}
	/** 清除验证器 */
	clearValidators = () => {
		this._validators = [];
		this._updateValid();
		return this;
	}

	/**
	 * 脏值
	 */
	_dirty = false;
	get dirty() {
		return this._dirty;
	}
	set dirty(val) {
		const isBoolean = Utils.isBoolean(val);
		const isSame = val === this._dirty;
		if (isBoolean === false || isSame) {
			return;
		}
		if (val) {
			this._dirty = true;
		} else {
			this._dirty = false;
			this._initValue = this.value;
		}
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	}
	_updateDirty = () => {
		// 上次结果
		const provDirty = this._dirty;
		this._dirty = this._initValue !== this._value;
		// 是否发生改变
		const isChanged = provDirty !== this._dirty;
		if (isChanged) {
			this.runDirtyChangeCallbacks(this._dirty);
		}
	}

	/**
	 * @description 错误
	 */
	_errors = [];
	get errors() {
		return this._errors;
	}


	/**
	 *  是否被禁用
	 */
	_disabled = false;
	get disabled() {
		return this._disabled;
	}
	set disabled(val) {
		const isBoolean = Utils.isBoolean(val);
		const isSame = val === this._disabled;
		if (isBoolean === false || isSame) {
			return;
		}
		this._disabled = val;
		this._updateDirty();
		this._updateValid();
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	}

	/** 必填 */
	_required = false;
	/** 设置必填 */
	setRequired = (val) => {
		const isBoolean = Utils.isBoolean(val);
		const isSame = val === this._required;
		if (isBoolean === false || isSame) {
			return this;
		}
		this._required = val;
		if (val) {
			this.addValidators('required');
		} else {
			this.removeValidators('required');
		}
		this._updateValid();
		if (this.parent) {
			this.parent.onCollectionChange();
		}
		return this;
	};
	/** 设置必填 */
	set required(val) {
		this.setRequired(val);
	};
	/** 必填 */
	get required() {
		return this._required;
	};



	/** placeholder */
	_placeholder = '';
	/** placeholder 改变，回调函数 */
	_placeholderChangeCallbacks = [];
	/** 设置，placeholder 改变时的回调 */
	placeholderChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._placeholderChangeCallbacks.push(callback);
		}
	};
	/** 运行，placeholder 改变的回调 */
	_runPlaceholderChangeCallbacks = (value) => {
		this._placeholderChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 设置 placeholder */
	set placeholder(val) {
		// placeholder 发生改变
		if (this._placeholder !== val) {
			this._placeholder = val;
			this._runPlaceholderChangeCallbacks(val);
		}
	};
	/** 设置 placeholder */
	setPlaceholder = (val) => {
		this.placeholder = val;
	};
	/** placeholder */
	get placeholder() {
		return this._placeholder;
	};

	/** 选择器样式 */
	_selectorStyle = {};
	/** 选择器样式改变，回调函数 */
	_selectorStyleChangeCallbacks = [];
	/** 设置选择器样式 时的回调 */
	selectorStyleChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._selectorStyleChangeCallbacks.push(callback);
		}
	};
	/** 运行，选择器样式 改变的回调 */
	_runSelectorStyleChangeCallbacks = (value) => {
		this._selectorStyleChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 设置选择器样式 */
	set selectorStyle(val) {
		// 选择器样式 发生改变
		if (Utils.isObject(val)) {
			this._selectorStyle = val;
			this._runSelectorStyleChangeCallbacks(val);
		}
	};
	/** 设置选择器样式 */
	setSelectorStyle = (val) => {
		this.selectorStyle = val;
	};
	/** 选择器样式 */
	get selectorStyle() {
		return this._selectorStyle;
	};

	/** 是否显示标签 */
	_showLabel = true;
	_showLabelChangeCallbacks = [];
	showLabelChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._showLabelChangeCallbacks.push(callback);
		}
	};
	_runShowLabelChangeCallbacks = (value) => {
		this._showLabelChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	get showLabel() {
		return this._showLabel;
	};
	set showLabel(val) {
		if(val === this._showLabel){
			return;
		}
		if (Utils.isBoolean(val)) {
			this._showLabel = val;
			this._runShowLabelChangeCallbacks(val);
		}
	};

	/** 标签样式 */
	_labelStyle = {};
	/** 标签样改变，回调函数 */
	_labelStyleChangeCallbacks = [];
	/** 设置标签样式 时的回调 */
	labelStyleChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._labelStyleChangeCallbacks.push(callback);
		}
	};
	/** 运行，标签样式 改变的回调 */
	_runLabelStyleChangeCallbacks = (value) => {
		this._labelStyleChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 设置标签样式 */
	set labelStyle(val) {
		// 标签样式 发生改变
		if (Utils.isObject(val)) {
			this._labelStyle = val;
			this._runLabelStyleChangeCallbacks(val);
		}
	};
	/** 标签样式 */
	get labelStyle() {
		return this._labelStyle;
	};

	/** 选择器样式 */
	_selectorStyle = {};
	/** 标签样改变，回调函数 */
	_selectorStyleChangeCallbacks = [];
	/** 设置标签样式 时的回调 */
	selectorStyleChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._selectorStyleChangeCallbacks.push(callback);
		}
	};
	/** 运行，标签样式 改变的回调 */
	_runSelectorStyleChangeCallbacks = (value) => {
		this._labelStyleChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 设置标签样式 */
	set selectorStyle(val) {
		// 标签样式 发生改变
		if (Utils.isObject(val)) {
			this._labelStyle = val;
			this._runSelectorStyleChangeCallbacks(val);
		}
	};
	/** 标签样式 */
	get selectorStyle() {
		return this._labelStyle;
	};

	/** 样式 */
	_style = {};
	/** 标签样改变，回调函数 */
	_styleChangeCallbacks = [];
	/** 设置标签样式 时的回调 */
	styleChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._styleChangeCallbacks.push(callback);
		}
	};
	/** 运行，标签样式 改变的回调 */
	_runStyleChangeCallbacks = (value) => {
		this._styleChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 设置标签样式 */
	set style(val) {
		// 标签样式 发生改变
		if (Utils.isObject(val)) {
			this._style = val;
			this._runStyleChangeCallbacks(val);
		}
	};
	/** 标签样式 */
	get style() {
		return this._style;
	};

	/** 颜色 */
	_color = '';
	_colorChangeCallbacks = [];
	colorChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._colorChangeCallbacks.push(callback);
		}
	};
	_runColorChangeCallbacks = (value) => {
		this._colorChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	get color() {
		return this._color;
	}
	setColor(val) {
		this.color = val;
	}
	/** 设置颜色 */
	set color(val) {
		if (this._color === val) {
			return;
		}
		this._color = val;
		this.setLabelStyle({ 'color': val });
		this.setSelectorStyle({ borderColor: val });
		this._runColorChangeCallbacks(val);
		// this._runLabelStyleChangeCallbacks({ borderColor: val });
	};
	/** 标签 */
	_label = '';
	/** 标签改变，回调函数 */
	_labelChangeCallbacks = [];
	/** 设置标签改变 时的回调 */
	labelChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._labelChangeCallbacks.push(callback);
		}
	};
	/** 运行，标签 改变的回调 */
	_runLabelChangeCallbacks = (value) => {
		this._labelChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 获取标签 */
	get label() {
		return this._label;
	}
	/** 设置标签 */
	set label(v) {
		if (this._label !== v) {
			this._runLabelChangeCallbacks(v);
			this._label = v;
		}
	}
	/** 设置标签 */
	setLabel = (v) => {
		this.label = v;
	}
	/** 显示值 */
	_showValue = undefined;
	/** 设置显示值 */
	set showValue(v) {
		this._showValue = v || this.value;
		this._runShowValueChangeCallbacks(this._showValue);
		// console.log(`set showValue:`, v, this._showValue)
	}
	/** 获取显示值 */
	get showValue() {
		return this._showValue;
	}
	/** 显示值改变，回调函数 */
	_showValueChangeCallbacks = [];

	/** 设置显示值改变 时的回调 */
	showValueChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._showValueChangeCallbacks.push(callback);
		}
	};
	/** 运行，显示值 改变的回调 */
	_runShowValueChangeCallbacks = (value) => {
		this._showValueChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};


	/** 选择器 */
	_selector = 'input';
	/** 获取选择器 */
	get selector() {
		return this._selector;
	}
	/** 设置选择器 */
	set selector(val) {
		if (this._selector !== val) {
			this._selector = val;
			this._runSelectorChangeCallbacks();
			if (this.parent) {
				this.parent.update();
			}
		}
	};
	/** 设置选择器 */
	setSelector = (val) => {
		this.selector = val;
	}
	/** 选择器 改变，回调函数 */
	_selectorChangeCallbacks = [];
	/** 运行，选择器 改变的回调 */
	_runSelectorChangeCallbacks = () => {
		this._selectorChangeCallbacks.forEach((callback) => {
			callback(this._selector);
		});
	};
	/** 设置，选择器 改变时的回调 */
	selectorChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._selectorChangeCallbacks.push(callback);
		}
	};

	/**
	 * @description FormControl数据
	 */
	controlData = {};

	/** 日志开关 */
	loggingSwitch = false;
	/** 日志 */
	logs = [];
	/** 下拉数据 */
	_options = [];
	/** 下拉数据改变，回调函数 */
	_optionsChangeCallbacks = [];
	/** 设置，下拉数据改变时的回调 */
	optionsChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._optionsChangeCallbacks.push(callback);
		}
	};
	/** 运行，下拉数据改变回调函数 */
	_runoptionsChangeCallbacks = (ops) => {
		this._optionsChangeCallbacks.forEach((callback) => {
			callback(ops);
		});
	};
	/** 选中的显示值 */
	get optionLable() {
		let result = [];
		if (Array.isArray(this.value)) {
			result = [];
			this.value.forEach(v => {
				const option = getOptionLable(v, this._options);
				if (option) {
					result.push(option.label);
				}
			});
		}
		return result;
	}
	/** 级联 label */
	get cascaderLable() {
		if (Utils.isEmpty(this.value)) {
			return '';
		}
		const arr = this.value.split(',');
		const numArr = arr.map((item) => {
			return isNaN(Number(item)) ? item : Number(item);
		});
		let result = [];
		numArr.forEach((v) => {
			const option = getOptionLable(v, this._options);
			if (option) {
				result.push(option.label);
			}
		});

		return result.join('/');
	}
	/** 级联 value */
	get cascaderValue() {
		if (Utils.isEmpty(this.value)) {
			return [];
		}
		const arr = this.value.split(',');
		const numArr = arr.map((item) => {
			return isNaN(Number(item)) ? item : Number(item);
		});

		return numArr;
	}

	/** select label */
	get selectLabel() {
		let result = '';
		if (this._options.length > 0) {
			const res = this._options.find(v => v.value === this.value);
			if (res !== undefined) {
				result = res.label;
			}
		}
		return result;
	}
	/** radio label */
	get radioLabel() {
		return this.selectLabel;
	}

	/** 获取下拉数据 */
	get options() {
		return this._options;
	}
	/** 设置下拉数据 */
	set options(ops) {
		this._options = ops;
		this._runoptionsChangeCallbacks(ops)
	}
	/** 设置下拉数据 */
	setOptions = (ops) => {
		this.options = ops;
	}

	/** 开始值 */
	_startValue = undefined;
	/** 获取开始值 */
	get startValue() {
		return this._startValue;
	}
	/** 设置开始值 */
	set startValue(v) {
		if (this._startValue === v) {
			return;
		}
		this._startValue = v;
		this._runStartValueChangeCallbacks(v);
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	}
	/** 设置开始值 */
	setStartValue = (v) => {
		this.startValue = v;
	};
	/** 开始值改变时 回调 */
	_startValueChangeCallbacks = [];
	/** 设置开始值改变时的回调 */
	startValueChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._startValueChangeCallbacks.push(callback);
		}
	};
	/** 运行，开始值改变的回调 */
	_runStartValueChangeCallbacks = (value) => {
		this._startValueChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 结束值 */
	_endValue = undefined;
	/** 获取结束值 */
	get endValue() {
		return this._endValue;
	}
	/** 设置结束值 */
	set endValue(v) {
		if (this._endValue === v) {
			return;
		}
		this._endValue = v;
		this._runEndValueChangeCallbacks(v);
		if (this.parent) {
			this.parent.onCollectionChange();
		}
	}
	/** 设置结束值 */
	setEndValue = (v) => {
		this.endValue = v;
	};
	/** 结束值改变时 回调 */
	_endValueChangeCallbacks = [];
	/** 设置结束值改变时的回调 */
	endValueChange = (callback) => {
		if (Utils.isFunction(callback)) {
			this._endValueChangeCallbacks.push(callback);
		}
	};
	/** 运行，结束值改变的回调 */
	_runEndValueChangeCallbacks = (value) => {
		this._endValueChangeCallbacks.forEach((callback) => {
			callback(value);
		});
	};
	/** 开始结束值数据类型 */
	startEndType = 'number';
	/** 显示错误回调 */
	setShowError = () => { };
	/** 跟新内部数据 */
	_updateControl = () => {
		this._options = this._options.concat([]);
		this.logs = this.logs.concat([]);
		return this;
	};
	/** 跟新内部数据 */
	update = () => {
		this._updateControl();
	};
	/** 按下回车的回调 */
	onPressEnter = undefined;

}
